/*
 * Copyright (c) 2016-2017 fulihui.com All right reserved
 * Project: information-core-170307
 * File name: CategoryStatisticsJob.java
 */

package com.fulihui.information.biz.job;


import com.fulihui.information.common.config.AppConst;
import com.fulihui.information.core.db.CategoryStatisticsDB;
import com.fulihui.information.core.redis.RedisCategoryStatisticsDB;
import com.fulihui.information.dal.dataobj.InfoCategory;
import com.fulihui.information.dal.dataobj.InfoCategoryExample;
import com.fulihui.information.dal.dataobj.InfoCategoryStatistics;
import com.fulihui.information.dal.mapper.InfoCategoryMapper;
import com.fulihui.information.dal.mapper.InfoCategoryStatisticsMapper;
import com.fulihui.information.util.LoggerNames;
import org.near.toolkit.common.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;

import static org.near.toolkit.common.DateUtils.addDays;
import static org.near.toolkit.common.DateUtils.formatShortFormat;

/**
 * @author Willard.Hu on 2017/2/16 0016.
 */
public class CategoryStatisticsJob {
    protected final transient Logger log = LoggerFactory.getLogger(LoggerNames.CATEGORY_STATISTICS_JOB_LOGGERNAME);

    @Autowired
    private InfoCategoryStatisticsMapper infoCategoryStatisticsMapper;
    @Autowired
    private InfoCategoryMapper infoCategoryMapper;
    @Autowired
    private RedisCategoryStatisticsDB redisCategoryStatisticsDB;

    public void execute() {
        // 查询耳朵所有已维护的类目，忽略是否显示
        InfoCategoryExample categoryExample = new InfoCategoryExample();
        categoryExample.createCriteria()
                .andProductCodeEqualTo("YOUKANTOU");
        List<InfoCategory> categoryList = infoCategoryMapper.selectByExample(categoryExample);
// 过滤热点
        // 计算前一天的日期字符串
        String date = formatShortFormat(addDays(new Date(), -1));
        categoryList.stream()
                .filter(it -> !StringUtil.equals(it.getCode(), AppConst.CONTENT_HOTS_CATEGORY_CODE))
                .map(InfoCategory::getCode).forEach(it -> {
            int retries = 0;
            while (retries < 3) {
                try {
                    doCalculateOfDay(it, date);
                    log.info("Category: {}, Date: {} 统计数量Redis同步到RDS成功", it, date);
                    break;
                } catch (Exception e) {
                    retries++;
                    log.error("Category:" + it + ", date:" + date
                            + ". 第" + retries + "次尝试, 执行数据同步失败, 失败原因: " + e.getMessage(), e);
                }
            }
        });
    }

    /**
     * 执行计算一天类目统计项的处理，包括插入数据和重置一天的缓存
     */
    private void doCalculateOfDay(String categoryCode, String date) {
        InfoCategoryStatistics record = new InfoCategoryStatistics();
        record.setCategoryCode(categoryCode);
        record.setDateInterval(date);
        for (CategoryStatisticsDB.StatisticType type : CategoryStatisticsDB.StatisticType.values()) {
            long times = redisCategoryStatisticsDB.get(categoryCode, type);
            switch (type) {
                case READ_TIMES:
                    record.setReadTimes((int) times);
                    break;
                case SHARED_TIMES:
                    record.setSharedTimes((int) times);
                    break;
                case STAR_TIMES:
                    record.setStarTimes((int) times);
                    break;
                case COMMENT_TIMES:
                    record.setCommentTimes((int) times);
                    break;
                case UPVOTE:
                    record.setVoteupTimes((int) times);
                    break;
                case DOWNVOTE:
                    record.setVotedownTimes((int) times);
                    break;
                default:
                    break;
            }
        }
        infoCategoryStatisticsMapper.insertSelective(record);
        redisCategoryStatisticsDB.reset(categoryCode);
    }

}
